<template>
  <demo-content :title="title">
    <div>
      <p>如下绘制的 canvas 用到下列 API：</p>
      <ul>
        <li>
          <code>
            arc(x, y, radius, startAngle, endAngle, counterclockwise) </code
          >: 圆弧绘制，<var>x</var>、<var>y</var> 表示圆心坐标,
          <var>radius</var>
          表示圆半径, <var>startAngle</var>/<var>endAngle</var>
          表示开始弧度和结束弧度，0度对应圆的最右侧点，<var
            >counterclockwise</var
          >
          表示是否逆时针，默认 false。 {{ canvasRef?.width }}
        </li>
        <li>beginPath()</li>
        <li>clearRect()</li>
        <li>fill()</li>
        <li>fillText()</li>
        <li>lineTo()</li>
        <li>moveTo()</li>
        <li>stroke()</li>
      </ul>
      <p>
        Canvas 可以让开发者先创建不可见路径，稍后再调用 stroke()
        绘制路径边缘或调用 fill() 对路径的内部进行填充。可以调用 beginPath()
        方法开始定义某一段路径。
      </p>
    </div>
    <canvas ref="canvasRef"></canvas>
  </demo-content>
</template>

<script setup lang="ts">
import { onMounted, ref } from "vue";
import { helper } from "./utils";

const title = "基本绘制-钟表";
// 指定组件上的属性
defineOptions({ title });

const canvasRef = ref<HTMLCanvasElement>();

function calcPos(centerX: number, centerY: number, r: number, angle: number) {
  const x = Math.cos(angle) * r + centerX;
  const y = Math.sin(angle) * r + centerY;
  return { x, y };
}

setInterval(updateTime, 1000);

function updateTime() {
  const canvas = canvasRef.value;
  if (!canvas) return;
  const ctx = canvas.getContext("2d")!;
  ctx.beginPath();
  const midX = 150;
  const midY = 75;
  ctx.clearRect(0, 0, 300, 150);
  const r = 60;
  // 时钟轮廓(空心圆)
  helper.arc.draw(ctx, { x: midX, y: midY, radius: r });

  // 中心点(实心圆)
  helper.arc.draw(ctx, { x: midX, y: midY, radius: 3, fillStyle: "#000" });

  // 时钟刻度
  for (let i = 1; i < 13; ++i) {
    const tr = r + 8;
    const lr = r - 4;
    const cosV = Math.cos((i * Math.PI) / 6);
    const sinV = Math.sin((i * Math.PI) / 6);
    const px = cosV * tr;
    const py = sinV * tr;
    const lx0 = cosV * lr + midX;
    const ly0 = sinV * lr + midY;
    const lx1 = cosV * (lr + 4) + midX;
    const ly1 = sinV * (lr + 4) + midY;
    ctx.beginPath();
    ctx.fillText((((i + 2) % 12) + 1).toString(), px + midX - 3, py + midY + 4);
    ctx.moveTo(lx0, ly0);
    ctx.lineTo(lx1, ly1);
    ctx.stroke();
    ctx.closePath();
  }
  const now = new Date();
  // 计算时间
  console.log(`${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}`);
  // 绘制时针
  const hourAngle =
    (now.getHours() + now.getMinutes() / 60) * (Math.PI / 6) - Math.PI / 2;
  const hourPos = calcPos(midX, midY, r - 20, hourAngle);
  ctx.beginPath();
  ctx.moveTo(midX, midY);
  ctx.lineTo(hourPos.x, hourPos.y);
  ctx.save();
  ctx.lineWidth = 5;
  ctx.stroke();
  ctx.restore();
  ctx.closePath();
  // 绘制分针
  const minuteAngle =
    (now.getMinutes() + now.getSeconds() / 60) * (Math.PI / 30) - Math.PI / 2;
  const minutePos = calcPos(midX, midY, r - 15, minuteAngle);
  ctx.beginPath();
  ctx.moveTo(midX, midY);
  ctx.lineTo(minutePos.x, minutePos.y);
  ctx.save();
  ctx.lineWidth = 3;
  ctx.stroke();
  ctx.restore();
  ctx.closePath();
  // 绘制秒针
  const secondAngle = now.getSeconds() * (Math.PI / 30) - Math.PI / 2;
  const secondPos = calcPos(midX, midY, r - 8, secondAngle);
  ctx.beginPath();
  ctx.moveTo(midX, midY);
  ctx.lineTo(secondPos.x, secondPos.y);
  ctx.save();
  ctx.lineWidth = 1;
  ctx.stroke();
  ctx.restore();
  ctx.closePath();
}
onMounted(updateTime);
</script>

<style src="./default.css" scoped></style>
